package com.hsogoo.avatar.transport.netty;

import com.hsogoo.avatar.enums.Protocol;
import com.hsogoo.avatar.model.AvatarRequest;
import com.hsogoo.avatar.model.AvatarResponse;
import com.hsogoo.avatar.model.AvatarTransporter;
import com.hsogoo.avatar.serialization.Serializer;
import com.hsogoo.avatar.serialization.SerializerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

/**
 * Created by za-huangsaigang on 2018/10/15.
 *
 *                                          Protocol
 *  ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐
 *       1   │   1   │       4      │
 *  ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤
 *           │       │              │
 *  │  Flag     Code     Body Size                    Body Content                                  │
 *           │       │              │
 *  └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
 *
 */
public class ProtocolEncoder extends MessageToByteEncoder<AvatarTransporter> {

    private final byte request_flag = 0X01;
    private final byte response_flag = 0X02;

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, AvatarTransporter msg, ByteBuf out) throws Exception {

        if(Protocol.AVATAR.equals(msg.protocol())){
            try {
                if (msg instanceof AvatarRequest) {
                    out.writeByte(request_flag);
                } else if (msg instanceof AvatarResponse) {
                    out.writeByte(response_flag);
                } else {
                    throw new IllegalArgumentException(msg.getClass().getSimpleName() + " transporter type is not support");
                }
                byte serializerCode = msg.serializerCode();
                out.writeByte(serializerCode);
                Serializer serializer = serializerCode == 0 ? SerializerFactory.getSerializer() : SerializerFactory.getSerializer(serializerCode);
                byte[] data = serializer.encode(msg);
                out.writeInt(data.length);
                out.writeBytes(data);
            } catch (Exception e){
                e.printStackTrace();
            }
        }else{
            throw new IllegalArgumentException(msg.protocol().name() + " protocol is not support");
        }
    }
}
